﻿using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Ditto.Helpers;
using Ditto.Models;

namespace Ditto.Controllers
{

    [HandleErrorWithELMAH]
    public class ItemsController : Controller
    {

        IItemRepository itemRepository;

        //
        // Dependency Injection enabled constructors

        public ItemsController()
            : this(new ItemRepository())
        {
        }

        public ItemsController(IItemRepository repository)
        {
            itemRepository = repository;
        }

        //
        // GET: /Items/
        //      /Items/Page/2
        //      /Items?q=term

        public ActionResult Index(string q, int? page)
        {

            const int pageSize = 25;

            IQueryable<Item> items = null;

            //Searching?
            if (!string.IsNullOrWhiteSpace(q))
                items = itemRepository.FindItemsByText(q).OrderBy(d => d.EventDate);
            else
                items = itemRepository.FindUpcomingItems();

            var paginatedItems = new PaginatedList<Item>(items, page ?? 0, pageSize);

            return View(paginatedItems);
        }

        //
        // GET: /Items/Details/5

        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new FileNotFoundResult { Message = "No Item found due to invalid item id" };
            }

            Item item = itemRepository.GetItem(id.Value);

            if (item == null)
            {
                return new FileNotFoundResult { Message = "No Item found for that id" };
            }

            return View(item);
        }

        //
        // GET: /Items/Edit/5

        [Authorize]
        public ActionResult Edit(int id)
        {

            Item item = itemRepository.GetItem(id);

            if (!item.IsPostedBy(User.Identity.Name))
                return View("InvalidOwner");

            return View(item);
            //return View(new ItemFormViewModel(item));
        }

        //
        // POST: /Items/Edit/5

        [HttpPost, Authorize]
        public ActionResult Edit(int id, FormCollection collection)
        {

            Item item = itemRepository.GetItem(id);

            if (!item.IsPostedBy(User.Identity.Name))
                return View("InvalidOwner");

            try
            {
                //foreach (string name in Request.Files)
                //{
                //    Image image = new Image(Request.Files[name]);
                //    ImageRepository imageRepository = new ImageRepository();
                //    imageRepository.AddItem(image, item);
                //}

                UpdateModel(item);

                itemRepository.Save();

                return RedirectToAction("Details", new { id = item.ItemID });
            }
            catch
            {
                return View(item);
                //return View(new ItemFormViewModel(item));
            }
        }

        //
        // GET: /Items/Create

        [Authorize]
        public ActionResult Create()
        {

            Item item = new Item()
            {
                TimeCreated = DateTime.Now,
                EventDate = DateTime.Now.AddDays(7),
                PostingUserID = User.Identity.Name,
                IsAvailable = true,

                ReturnDate = DateTime.Now.AddDays(14)
            };

            return View(item);
            //return View(new ItemFormViewModel(item));
        }

        //
        // POST: /Items/Create

        [HttpPost, Authorize]
        public ActionResult Create(Item item)
        {

            if (ModelState.IsValid)
            {
                DittoUserIdentity dittoUser = (DittoUserIdentity)User.Identity;
                item.PostingUserID = dittoUser.Name;

                itemRepository.Add(item);
                itemRepository.Save();

                return RedirectToAction("Details", new { id = item.ItemID });
            }

            return View(item);
            //return View(new ItemFormViewModel(item));
        }

        //
        // HTTP GET: /Items/Delete/1

        [Authorize]
        public ActionResult Delete(int id)
        {

            Item item = itemRepository.GetItem(id);

            if (item == null)
                return View("NotFound");

            if (!item.IsPostedBy(User.Identity.Name))
                return View("InvalidOwner");

            return View(item);
        }

        // 
        // HTTP POST: /Items/Delete/1

        [HttpPost, Authorize]
        public ActionResult Delete(int id, string confirmButton)
        {

            Item item = itemRepository.GetItem(id);

            if (item == null)
                return View("NotFound");

            if (!item.IsPostedBy(User.Identity.Name))
                return View("InvalidOwner");

            itemRepository.Delete(item);
            itemRepository.Save();

            return View("Deleted");
        }

        protected override void HandleUnknownAction(string actionName)
        {
            throw new HttpException(404, "Action not found");
        }

        public ActionResult Confused()
        {
            return View();
        }

        public ActionResult Trouble()
        {
            return View("Error");
        }

        [Authorize]
        public ActionResult My()
        {

            DittoUserIdentity dittoUser = (DittoUserIdentity)User.Identity;
            var userItems = from item in itemRepository.FindAllItems()
                              where
                                (
                                String.Equals(item.PostingUserID, dittoUser.Name)
                                //    ||
                                //item.RSVPs.Any(r => r.AttendeeNameId == dittoUser.Name || (r.AttendeeNameId == null && r.AttendeeName == dittoUser.Name))
                                )
                              orderby item.EventDate
                              select item;

            return View(userItems);
        }

        public ActionResult Photo(int id)
        {
            throw new NotImplementedException();
        }

        [HttpPost, Authorize]
        public ActionResult AddPhoto(int id, HttpPostedFileBase file)
        {
            ItemRepository itemRepository = new ItemRepository();
            ImageRepository imageRepository = new ImageRepository();

            Item item = itemRepository.GetItem(id);

            if (!item.IsPostedBy(User.Identity.Name))
                return View("InvalidOwner");

            try
            {
                Image image = new Image(file);
                imageRepository.AddItemImage(image, item);

                UpdateModel(item, "Item");

                itemRepository.Save();

                return RedirectToAction("Details", new { id = item.ItemID });
            }
            catch
            {
                return RedirectToAction("Details", new { id = item.ItemID });
            }
        }

        [Authorize]
        public ActionResult DeletePhoto(int id)
        {
            ItemRepository itemRepository = new ItemRepository();
            ImageRepository imageRepository = new ImageRepository();

            Item item = itemRepository.GetItem(id);

            if (!item.IsPostedBy(User.Identity.Name))
                return View("InvalidOwner");

            try
            {
                imageRepository.DeleteItemImage(item);

                UpdateModel(item, "Item");

                itemRepository.Save();

                return RedirectToAction("Details", new { id = item.ItemID });
            }
            catch
            {
                return View(item);
            }
        }

        [Authorize]
        public ActionResult RequestStatus(int id)
        {
            Request request = this.itemRepository.FindRequest(id, User.Identity.Name);

            RequestStatus status = new RequestStatus(id);
            if (request == null)
                status.Type = Models.RequestStatus.StatusType.None;
            else
            {
                if (!request.IsApproved.HasValue)
                    status.Type = Models.RequestStatus.StatusType.Requesting;
                else
                {
                    if (request.IsApproved.Value)
                        status.Type = Models.RequestStatus.StatusType.Approved;
                    else
                        status.Type = Models.RequestStatus.StatusType.Rejected;
                }

            }

            return PartialView(status);
        }

        [Authorize]
        public ActionResult SubmitRequest(int id)
        {
            Request request = this.itemRepository.FindRequest(id, User.Identity.Name);
            if (request == null)
            {
                request = Ditto.Models.Request.CreateRequest(0, id, User.Identity.Name);
                this.itemRepository.Add(request);
                this.itemRepository.Save();
            }

            RequestStatus status = new RequestStatus(id);
            status.Type = Models.RequestStatus.StatusType.Requesting;

            return PartialView("RequestStatus", status);
        }

        [Authorize]
        public ActionResult CancelRequest(int id)
        {
            Request request = this.itemRepository.FindRequest(id, User.Identity.Name);

            if (request != null)
            {
                this.itemRepository.Delete(request);
                this.itemRepository.Save();
            }

            RequestStatus status = new RequestStatus(id);
            status.Type = Models.RequestStatus.StatusType.None;

            return PartialView("RequestStatus", status);
        }

        [Authorize]
        public ActionResult RequestingUsers(int id)
        {
            var users = this.itemRepository.FindRequestingUsers(id);
            return PartialView(new ItemRequests(users));
        }

        public ViewResult ItemsRequested(string userID)
        {
            var items = this.itemRepository.FindItemsRequested(userID);
            return View(items);
        }

        public ViewResult ItemsRequesting(string userID)
        {
            var items = this.itemRepository.FindItemsRequesting(userID);
            return View(items);
        }

        public ActionResult RelatedTransaction(int id)
        {
            Transaction tran = this.itemRepository.FindTransaction(id);

            return RedirectToAction("Details", "Transactions", new { id = tran.TransactionID });
        }

        public ActionResult ItemComments()
        {
            return View();
        }

        public ActionResult WebSlicePopular()
        {
            ViewData["Title"] = "Popular Items";
            var model = from item in itemRepository.FindUpcomingItems()
                        //orderby item.RSVPs.Count descending
                        select item;

            return View("WebSlice", model.Take(5));
        }

        public ActionResult WebSliceUpcoming()
        {
            ViewData["Title"] = "Upcoming Items";
            DateTime d = DateTime.UtcNow.AddMonths(-3);
            var model = from item in itemRepository.FindUpcomingItems()
                        where item.TimeCreated > d
                        orderby item.TimeCreated descending
                        select item;

            return View("WebSlice", model.Take(5));
        }
    }
}